package com.dianping.statistics;

import java.util.concurrent.atomic.AtomicInteger;

import android.database.Cursor;
import android.database.DatabaseUtils;
import android.database.sqlite.SQLiteDatabase;

import com.dennytech.tac.utils.DataCursor;
import com.dennytech.tac.utils.DatabaseCursor;
import com.dennytech.tac.utils.Log;

public class StatisticsDB {
	private static final String TAG = StatisticsDB.class.getSimpleName();

	private static final String TABLE_NAME = "statistics";
	private static final String FD_TIME = "time";
	private static final String FD_DATA = "raw";
	protected SQLiteDatabase db;
	protected final AtomicInteger count = new AtomicInteger();
	protected volatile long maxId = 0;
	private DatabaseUtils.InsertHelper insertHelper;
	private int iTime, iData;

	public StatisticsDB(SQLiteDatabase db) {
		this.db = db;

		try {
			db.execSQL("CREATE TABLE IF NOT EXISTS " + TABLE_NAME + " (" + FD_TIME
					+ " INT8, " + FD_DATA + " TEXT);");

			Cursor c = db.rawQuery("SELECT COUNT(*) FROM " + TABLE_NAME, null);
			try {
				if (c.moveToFirst()) {
					count.set(c.getInt(0));
				}
			} finally {
				c.close();
			}

			c = db.rawQuery("SELECT MAX(_ROWID_) FROM " + TABLE_NAME, null);
			try {
				if (c.moveToFirst()) {
					maxId = c.getLong(0);
				}
			} finally {
				c.close();
			}

			insertHelper = new DatabaseUtils.InsertHelper(db, TABLE_NAME);
			iTime = insertHelper.getColumnIndex(FD_TIME);
			iData = insertHelper.getColumnIndex(FD_DATA);
		} catch (Exception e) {
			Log.e(TAG, e.getLocalizedMessage());
		}
	}

	public void close() {
		if (db != null) {
			db = null;
			insertHelper.close();
			insertHelper = null;
		}
	}

	public int count() {
		return count.get();
	}

	public long maxId() {
		return maxId;
	}

	public long push(String data, long time) {
		if (db == null)
			return -1;
		synchronized (insertHelper) {
			insertHelper.prepareForInsert();
			insertHelper.bind(iTime, time);
			insertHelper.bind(iData, data);
			long i;
			if ((i = insertHelper.execute()) < 0) {
				return -1;
			} else {
				count.incrementAndGet();
				if (i > maxId)
					maxId = i;
				else {
					Log.e(TAG, "_ROWID_ NOT INCREASE: " + i + ", " + maxId);
					Cursor c = db.rawQuery("SELECT MAX(_ROWID_) FROM "
							+ TABLE_NAME, null);
					try {
						if (c.moveToFirst()) {
							maxId = c.getLong(0);
						}
					} finally {
						c.close();
					}
				}
				return i;
			}
		}
	}

	public long push(String data) {
		return push(data, System.currentTimeMillis());
	}

	private final String[] _q_1 = { FD_DATA };

	@SuppressWarnings("unchecked")
	public DataCursor<String> queryBeforeId(long id) {
		if (db == null)
			return DataCursor.EMPTY_CURSOR;
		Cursor c = db.query(TABLE_NAME, _q_1, "_ROWID_<=" + id, null, null,
			null, null);
		return new StrCursor(c);
	}

	public boolean deleteBeforeId(long id) {
		if (db == null)
			return false;

		int c = 0;
		try {
		    c = db.delete(TABLE_NAME, "_ROWID_<=" + id, null);
		} catch (Exception e) {
			Log.e(TAG, e.getLocalizedMessage());
		}
		count.addAndGet(-c);
		return c > 0;
	}

	static class StrCursor extends DatabaseCursor<String> {
		public StrCursor(Cursor c) {
			super(c);
		}

		@Override
		protected String getData(Cursor c) {
			return c.getString(0);
		}
	}
}
